"""
插件管理器
负责插件的加载、注册、启动和停止
"""
import os
import sys
import importlib
import importlib.util
from typing import Dict, List, Optional, Any
from pathlib import Path
from datetime import datetime
import logging

from .base import BasePlugin, PluginInfo, PluginConfig

logger = logging.getLogger(__name__)


class PluginManager:
    """插件管理器"""
    
    def __init__(self, plugins_dir: str = "plugins"):
        self.plugins_dir = Path(plugins_dir)
        self.plugins: Dict[str, BasePlugin] = {}
        self.plugins_info: Dict[str, PluginInfo] = {}
        self.plugins_config: Dict[str, PluginConfig] = {}
        
        # 确保插件目录存在
        self.plugins_dir.mkdir(exist_ok=True)
        
        # 初始化时加载所有插件
        self.load_all_plugins()
    
    def load_all_plugins(self) -> None:
        """加载所有插件"""
        if not self.plugins_dir.exists():
            return
        
        for plugin_file in self.plugins_dir.glob("*.py"):
            if plugin_file.name.startswith("__"):
                continue
            try:
                self.load_plugin(plugin_file)
            except Exception as e:
                logger.error(f"加载插件 {plugin_file.name} 失败: {e}")
    
    def load_plugin(self, plugin_path: Path) -> Optional[BasePlugin]:
        """加载单个插件"""
        try:
            # 动态导入插件模块
            spec = importlib.util.spec_from_file_location(
                plugin_path.stem, plugin_path
            )
            module = importlib.util.module_from_spec(spec)
            sys.modules[plugin_path.stem] = module
            spec.loader.exec_module(module)
            
            # 查找插件类
            plugin_class = None
            for attr_name in dir(module):
                attr = getattr(module, attr_name)
                if (isinstance(attr, type) and 
                    issubclass(attr, BasePlugin) and 
                    attr != BasePlugin):
                    plugin_class = attr
                    break
            
            if not plugin_class:
                logger.warning(f"在 {plugin_path.name} 中未找到插件类")
                return None
            
            # 创建插件实例
            plugin = plugin_class()
            plugin.info = plugin.get_info()
            plugin.config = self.plugins_config.get(
                plugin.info.name, 
                PluginConfig()
            )
            
            # 初始化插件
            if plugin.initialize():
                plugin.is_loaded = True
                self.plugins[plugin.info.name] = plugin
                self.plugins_info[plugin.info.name] = plugin.info
                self.plugins_config[plugin.info.name] = plugin.config
                
                # 如果配置为自动启动，则启动插件
                if plugin.config.auto_start:
                    self.start_plugin(plugin.info.name)
                
                logger.info(f"插件 {plugin.info.name} 加载成功")
                return plugin
            else:
                logger.error(f"插件 {plugin_path.name} 初始化失败")
                return None
                
        except Exception as e:
            logger.error(f"加载插件 {plugin_path.name} 时发生错误: {e}")
            return None
    
    def unload_plugin(self, plugin_name: str) -> bool:
        """卸载插件"""
        if plugin_name not in self.plugins:
            return False
        
        plugin = self.plugins[plugin_name]
        
        # 如果插件正在运行，先停止它
        if plugin.is_active:
            self.stop_plugin(plugin_name)
        
        # 卸载插件
        try:
            plugin.is_loaded = False
            del self.plugins[plugin_name]
            del self.plugins_info[plugin_name]
            logger.info(f"插件 {plugin_name} 卸载成功")
            return True
        except Exception as e:
            logger.error(f"卸载插件 {plugin_name} 失败: {e}")
            return False
    
    def start_plugin(self, plugin_name: str) -> bool:
        """启动插件"""
        if plugin_name not in self.plugins:
            return False
        
        plugin = self.plugins[plugin_name]
        
        if not plugin.is_loaded:
            logger.error(f"插件 {plugin_name} 未加载")
            return False
        
        if plugin.is_active:
            logger.warning(f"插件 {plugin_name} 已经在运行")
            return True
        
        try:
            if plugin.start():
                plugin.is_active = True
                logger.info(f"插件 {plugin_name} 启动成功")
                return True
            else:
                logger.error(f"插件 {plugin_name} 启动失败")
                return False
        except Exception as e:
            logger.error(f"启动插件 {plugin_name} 时发生错误: {e}")
            return False
    
    def stop_plugin(self, plugin_name: str) -> bool:
        """停止插件"""
        if plugin_name not in self.plugins:
            return False
        
        plugin = self.plugins[plugin_name]
        
        if not plugin.is_active:
            logger.warning(f"插件 {plugin_name} 未在运行")
            return True
        
        try:
            if plugin.stop():
                plugin.is_active = False
                logger.info(f"插件 {plugin_name} 停止成功")
                return True
            else:
                logger.error(f"插件 {plugin_name} 停止失败")
                return False
        except Exception as e:
            logger.error(f"停止插件 {plugin_name} 时发生错误: {e}")
            return False
    
    def get_all_plugins(self) -> List[Dict[str, Any]]:
        """获取所有插件信息"""
        plugins = []
        for name, plugin in self.plugins.items():
            plugins.append({
                "name": name,
                "status": plugin.get_status(),
                "info": self.plugins_info[name].dict(),
                "config": self.plugins_config[name].dict()
            })
        return plugins
    
    def get_active_plugins(self) -> List[Dict[str, Any]]:
        """获取活跃插件信息"""
        return [
            plugin for plugin in self.get_all_plugins()
            if plugin["status"]["active"]
        ]
    
    def get_plugin(self, plugin_name: str) -> Optional[Dict[str, Any]]:
        """获取指定插件信息"""
        if plugin_name not in self.plugins:
            return None
        
        plugin = self.plugins[plugin_name]
        return {
            "name": plugin_name,
            "status": plugin.get_status(),
            "info": self.plugins_info[plugin_name].dict(),
            "config": self.plugins_config[plugin_name].dict()
        }
    
    def update_plugin_config(self, plugin_name: str, config: PluginConfig) -> bool:
        """更新插件配置"""
        if plugin_name not in self.plugins:
            return False
        
        self.plugins_config[plugin_name] = config
        self.plugins[plugin_name].set_config(config)
        return True
    
    def reload_plugin(self, plugin_name: str) -> bool:
        """重新加载插件"""
        if self.unload_plugin(plugin_name):
            plugin_file = self.plugins_dir / f"{plugin_name}.py"
            if plugin_file.exists():
                return self.load_plugin(plugin_file) is not None
        return False 